CFE-2986: Added getdir command to cf-net, copies directory and files#6049
CFE-2986: Added getdir command to cf-net, copies directory and files#6049SimonThalvorsen wants to merge 1 commit intocfengine:masterfrom
Conversation
f7cebad to
40a6c09
Compare
larsewi
left a comment
There was a problem hiding this comment.
It would be nicer if we extended cf-net get to get both files and directories, instead of having two separate sub-commands. Please investigate how rsync does this and try to do it in a similar way here.
@larsewi on the other hand, cf-net was written mainly as a protocol testing tool, and the commands mirror their protocol command names. If the There is also some advantage to not being too dynamic with this stuff. If you make a CLI that forces the user to specify if they are copying a file or a folder, you can prevent some annoying / confusing situations. We could for example make a new subcommand, |
40a6c09 to
2bd2729
Compare
larsewi
left a comment
There was a problem hiding this comment.
Please break this up a little. Maybe a recursive solution would be more elegant given that it is a recursive problem.
2bd2729 to
e9f4cb3
Compare
e9f4cb3 to
5b55d16
Compare
larsewi
left a comment
There was a problem hiding this comment.
There should be a recursion depth limit to prevent a potential malicious or misconfigured server with symlink loops (or deeply nested dirs) to cause stack overflow.
We should probably stick to a maximum path size for the same reasons above.
d68100f to
047b068
Compare
larsewi
left a comment
There was a problem hiding this comment.
Make sure to check return values of functions. It's OK to do best effort. I.e., we encounter an error but continue if it's safe. But in this case we need to cache the error so that we can later exit with failure. For some errors, like if we fail to create a directory, it does not make sense to try to fetch the files that should be in that directory afterwards.
62eb2df to
c2b59c7
Compare
larsewi
left a comment
There was a problem hiding this comment.
It's starting to look good. Just a few more nitpicks. Almost there!
c2b59c7 to
38becec
Compare
38becec to
1b062de
Compare
larsewi
left a comment
There was a problem hiding this comment.
It's starting to look very good
| } | ||
| } | ||
|
|
||
| args = &(args[optind]); |
There was a problem hiding this comment.
There's no check that a positional argument remains. Running cf-net getdir -o /tmp/ (no remote dir) will probably dereference NULL
There was a problem hiding this comment.
You are still dereferencing args[optind] here without checking that there is anything there first
Ticket: CFE-2986 Changelog: Title Signed-off-by: Simon Halvorsen <simon.halvorsen@northern.tech>
1b062de to
04e28f6
Compare
larsewi
left a comment
There was a problem hiding this comment.
Getting there! Still a few things to address before this is ready to merge
| ret = process_dir_recursive(conn, | ||
| remote_full, | ||
| local_full, | ||
| print_stats, | ||
| (limit - 1)); |
There was a problem hiding this comment.
Indents here (using 8 spaces) are a bit inconsistent with the rest of the code base
| } | ||
|
|
||
| // Helper: Recursively process directory entries | ||
| static int process_dir_recursive(AgentConnection *conn, |
There was a problem hiding this comment.
A doc comment explaining the return values or a self documenting enum would be nice
| } | ||
|
|
||
| // Helper: Sets up local directory filepath | ||
| bool static SetupLocalDirectoryPath(char *const base, char **local_dir) |
There was a problem hiding this comment.
Redundant comment. The function name already conveys this. The comment should answer things the signature can't tell you. Otherwise it should not be there. A better comment would for example explain what the base argument does. Because this is not obvious from the signature alone. There's a few more comments like this in the code. You can consider removing or changing them.
| char temp[PATH_MAX]; | ||
|
|
||
| int written = snprintf(temp, sizeof(temp), "%s/%s/", *local_dir, base); | ||
| printf("tmp;%s\n", temp); |
There was a problem hiding this comment.
This looks like some left-over from debugging?
| return false; | ||
| } | ||
| free(*local_dir); | ||
| *local_dir = xstrdup(temp); |
There was a problem hiding this comment.
Here you could use StringFormat() instead. Or since the you are limiting the buffer to PATH_MAX you can require the caller to allocate it. This way the caller can allocate it on the stack.
| Log(LOG_LEVEL_ERR, "Path too long for local path: %s/%s/", | ||
| *local_dir, base); | ||
| free(*local_dir); | ||
| free(base); |
There was a problem hiding this comment.
It very unexpected that this function free's something allocated by the elsewhere. The caller should be responsible.
| if (local_dir != NULL) | ||
| { | ||
| Log(LOG_LEVEL_INFO, | ||
| "Warning: multiple occurrences of -o in command, "\ | ||
| "only last one will be used."); | ||
| free(local_dir); | ||
| } | ||
| local_dir = xstrdup(optarg); | ||
| break; |
There was a problem hiding this comment.
Maybe it would be better to just return failure here?
| printf("Default optarg = '%s', c = '%c' = %i\n", | ||
| optarg, c, (int)c); | ||
| break; |
| } | ||
| } | ||
|
|
||
| args = &(args[optind]); |
There was a problem hiding this comment.
You are still dereferencing args[optind] here without checking that there is anything there first
Ticket: CFE-2986
Changelog: Title